package com.jzlin.funhub.admin.controller;

import com.jzlin.funhub.admin.model.entity.FileStorage;
import com.jzlin.funhub.admin.model.resp.FileUploadResp;
import com.jzlin.funhub.admin.service.file.FileManagerService;
import com.jzlin.funhub.framework.core.http.RestRet;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

/**
 * 文件存储控制器.
 *
 * @author linjz
 * @since 2025/8/10
 */
@RestController
@Api(tags = {"文件存储"})
@RequestMapping("/file")
public class FileController {
    @Autowired
    private FileManagerService fileManagerService;

    @ApiOperation("文件上传")
    @PostMapping("/upload")
    public RestRet<FileUploadResp> pageArticle(@RequestParam MultipartFile file, @RequestParam String businessType) {
        return RestRet.createSuccessRet(fileManagerService.upload(file, businessType));
    }

    @ApiOperation("文件下载")
    @GetMapping("/download")
    public ResponseEntity<Resource> downloadFile(@RequestParam String fileId) {
        InputStream inputStream = fileManagerService.download(fileId);
        InputStreamResource resource = new InputStreamResource(inputStream);

        FileStorage fileStorage = fileManagerService.getByFileId(fileId);
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(determineContentType(fileStorage.getFileExtension())))
                .header(HttpHeaders.CACHE_CONTROL, "public, max-age=86400") // 缓存1天
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileStorage.getOriginalFilename() + "\"")
                .body(resource);
    }

    /**
     * 根据文件扩展名确定Content-Type
     */
    private String determineContentType(String extension) {
        switch (extension) {
            case "png":
                return "image/png";
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "gif":
                return "image/gif";
            case "webp":
                return "image/webp";
            default:
                return "application/octet-stream";
        }
    }
}
